﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace CXW.Core
{
    public class Security
    {
        static string _queryStringKey = "abcdefgh"; //URL传输参数加密Key 
        static string _passWordKey = "hgfedcba";  //PassWord加密Key 

        /// <summary>URL传输参数加密Key</summary>
        public static string QueryStringKey
        {
            get { return _queryStringKey; }
            set { _queryStringKey = value; }
        }
        /// <summary>PassWord加密Key </summary>
        public static string PassWordKey
        {
            get { return _passWordKey; }
            set { _passWordKey = value; }
        }
        /// <summary>加密帐号口令  </summary>
        /// <param name="PassWord"></param>
        public static string EncryptPassWord(string PassWord)
        {
            return Encrypt(PassWord, _passWordKey);
        }

        /// <summary>解密帐号口令 </summary>
        /// <param name="PassWord"></param>
        public static string DecryptPassWord(string PassWord)
        {
            return Decrypt(PassWord, _passWordKey);
        }

        /// <summary>加密</summary>
        /// <param name="pToEncrypt"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string Encrypt(string pToEncrypt, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();  //把字符串放到byte数组中   

            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
            //byte[]  inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);   

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  //建立加密对象的密钥和偏移量 
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);   //原文使用ASCIIEncoding.ASCII方法的GetBytes方法  
            MemoryStream ms = new MemoryStream();     //使得输入密码必须输入英文文本 
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        /// <summary>解密</summary>
        /// <param name="pToDecrypt"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string Decrypt(string pToDecrypt, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
            for (int x = 0; x < pToDecrypt.Length / 2; x++)
            {
                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  //建立加密对象的密钥和偏移量，此值重要，不能修改   
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);

            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();  //建立StringBuild对象，CreateDecrypt使用的是流对象，必须把解密后的文本变成流对象   

            return Encoding.Default.GetString(ms.ToArray());
        }

        /// <summary>检查己加密的字符串是否与原文相同 </summary>
        /// <param name="EnString"></param>
        /// <param name="FoString"></param>
        /// <param name="Mode"></param>
        /// <returns></returns>
        public static bool ValidateString(string EnString, string FoString, int Mode)
        {
            switch (Mode)
            {
                default:
                case 1:
                    if (Decrypt(EnString, _queryStringKey) == FoString.ToString())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                case 2:
                    if (Decrypt(EnString, _passWordKey) == FoString.ToString())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
            }
        }
    }
}
